package com.hko.qrip.service.impl;

import it.sauronsoftware.ftp4j.FTPFile;

import java.io.File;
import java.io.FilenameFilter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;

import org.springframework.beans.factory.annotation.Autowired;

import com.hko.qrip.bean.TdwrAlert;
import com.hko.qrip.dao.FtpLogDao;
import com.hko.qrip.dao.TdwrDao;
import com.hko.qrip.manager.FTPManager;
import com.hko.qrip.service.TdwrService;
import com.hko.qrip.util.QripJobOptions;

public class TdwrServiceImpl implements TdwrService {

	private static String MESSAGE_HEADER = "OWWS Alpha TDWR Message";
	private static String END_MESSAGE = "Message";
	private static String TIMEROW = "sensor data time";
	private static String MESSAGE_OFFSET = "message offset";
	private static String MESSAGE_LENGTH = "message length";
	private static String ALERT_TYPE = "alert type";
	private static String ALERT_SEVERITY = "alert severity";
	private static String RUNWAY_ARENA = "runway arena";
	private static String RUNWAY_POSITION = "runway position";
	private static String CORRIDOR = "name:";

	private static SimpleDateFormat sdf = new SimpleDateFormat("E MMM d HH:mm:ss yyyy", Locale.US);
	@Autowired
	private QripJobOptions jobOptions;

	@Autowired
	private TdwrDao tdwrDao;

	@Autowired
	private FtpLogDao ftpLogDao;

	@Override
	public int insertTdwrAlert(TdwrAlert alert) throws SQLException {
		return tdwrDao.insertTdwrAlert(alert);
	}

	@Override
	public void doSync() throws Exception {
		System.out.println("[INFO] Tdwr sync service started");
		File[] files = downloadFiles();
		for (File file : files) {
			List<TdwrAlert> alerts = getAlertFile(file);
			int changeCount = 0;
			for (TdwrAlert alert : alerts) {
				changeCount += insertTdwrAlert(alert);
			}
			System.out.println(changeCount + " alerts inserted");
			ftpLogDao.insertTableLog(file.getName(), changeCount, alerts.size(), "");
			file.delete();
		}
		System.out.println("[INFO] Tdwr sync service ended");

	}

	private File[] downloadFiles() throws Exception {
		FTPManager fm = new FTPManager(jobOptions.getFtpHost(), jobOptions.getFtpUser(), jobOptions.getFtpPassword());
		fm.ftpLogin();
		fm.changeDir(jobOptions.getFtpPath());
		FTPFile[] files = fm.listFiles("tdwr*");
		for (FTPFile file : files) {
			fm.downloadAndDeleteFile(jobOptions.getLocalFilePath() + file.getName(), file.getName());
			System.out.println("downloaded: " + file.getName());
			ftpLogDao.insertFtpLog(file.getName());
		}
		fm.close();

		File lrDir = new File(jobOptions.getLocalFilePath());
		File[] lrFiles = lrDir.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File arg0, String arg1) {
				if (arg1.contains("tdwr")) {
					return true;
				}
				return false;
			}
		});

		return lrFiles;
	}

	private List<TdwrAlert> getAlertFile(File file) throws Exception {
		List<TdwrAlert> resultList = new ArrayList<TdwrAlert>();

		Scanner fin = new Scanner(file);
		Timestamp lineTs = new Timestamp(0L);
		boolean isAlphaMessage = false;
		boolean isTimeAbl = false;
		int checkDigit = 0;
		TdwrAlert alert = null;
		while (fin.hasNextLine()) {
			String line = fin.nextLine().trim();
			if (!isAlphaMessage) {
				if (line.contains(MESSAGE_HEADER)) {
					isAlphaMessage = true;
				}
				continue;
			} else {
				if (line.contains(END_MESSAGE)) {
					isAlphaMessage = false;
					isTimeAbl = false;
					continue;
				}
				if (line.contains(TIMEROW)) {
					Date date = sdf.parse(line.split("time:")[1].trim());
					lineTs = new Timestamp(date.getTime());
					isTimeAbl = true;
					continue;
				}
				if (!isTimeAbl)
					continue;
				if (line.split(":").length > 1) {
					String lineData = line.split(":")[1].trim();
					if (line.contains(MESSAGE_OFFSET)) {
						alert = new TdwrAlert();
						alert.setDatetime(lineTs);
						alert.setMessageOffset(Integer.parseInt(lineData));
						checkDigit = 100;
					} else if (line.contains(MESSAGE_LENGTH)) {
						alert.setMessageLength(Integer.parseInt(lineData));
						checkDigit++;
					} else if (line.contains(ALERT_TYPE)) {
						alert.setAlertType(Integer.parseInt(lineData));
						checkDigit++;
					} else if (line.contains(ALERT_SEVERITY)) {
						alert.setAlertSeverity(Integer.parseInt(lineData));
						if (alert.getAlertSeverity() < 15 && alert.getAlertSeverity() > -15) {
							checkDigit += 1000;
						}
						checkDigit++;
					} else if (line.contains(RUNWAY_ARENA)) {
						alert.setRunwayArena(Integer.parseInt(lineData));
						checkDigit++;
					} else if (line.contains(RUNWAY_POSITION)) {
						alert.setRunwayPosition(Integer.parseInt(lineData));
						checkDigit++;
					} else if (line.contains(CORRIDOR)) {
						alert.setCorridor(lineData);
						if (checkDigit == 105) {
							resultList.add(alert);
						} else if (checkDigit < 1000) {
							System.out.println("WARNING!! WRONG TDWR FORMAT");
						}
					}
				}
			}
		}
		fin.close();

		return resultList;
	}
}
